<template>
    <view
        v-if="show"
        class="u-notice-bar"
        :style="{
            background: computeBgColor,
            padding: padding
        }"
        :class="[
            type ? `u-type-${type}-light-bg` : ''
        ]"
    >
        <view class="u-direction-row">
            <view class="u-icon-wrap">
                <u-icon class="u-left-icon" v-if="volumeIcon" name="volume-fill" :size="volumeSize" :color="computeColor"></u-icon>
            </view>
            <view class="u-notice-box" id="u-notice-box">
                <view
                    class="u-notice-content"
                    id="u-notice-content"
                    :style="{
                        animationDuration: animationDuration,
                        animationPlayState: animationPlayState,
                    }"
                >
                    <text class="u-notice-text" @tap="click" :style="[textStyle]"
                    :class="['u-type-' + type]">{{showText}}</text>
                </view>
            </view>
            <view class="u-icon-wrap">
                <u-icon @click="getMore" class="u-right-icon" v-if="moreIcon" name="arrow-right" :size="26" :color="computeColor"></u-icon>
                <u-icon @click="close" class="u-right-icon" v-if="closeIcon" name="close" :size="24" :color="computeColor"></u-icon>
            </view>
        </view>
    </view>
</template>
<script>
export default {
    props: {
        // 显示的内容，数组
        list: {
            type: Array,
            default() {
                return [];
            }
        },
        // 显示的主题，success|error|primary|info|warning|none
        // none主题默认为透明背景，黑色(contentColor)字体
        type: {
            type: String,
            default: 'warning'
        },
        // 是否显示左侧的音量图标
        volumeIcon: {
            type: Boolean,
            default: true
        },
        // 是否显示右侧的右箭头图标
        moreIcon: {
            type: Boolean,
            default: false
        },
        // 是否显示右侧的关闭图标
        closeIcon: {
            type: Boolean,
            default: false
        },
        // 是否自动播放
        autoplay: {
            type: Boolean,
            default: true
        },
        // 文字颜色，各图标也会使用文字颜色
        color: {
            type: String,
            default: ''
        },
        // 背景颜色
        bgColor: {
            type: String,
            default: ''
        },
        // 是否显示
        show: {
            type: Boolean,
            default: true
        },
        // 字体大小，单位rpx
        fontSize: {
            type: [Number, String],
            default: 26
        },
        // 音量喇叭的大小
        volumeSize: {
            type: [Number, String],
            default: 34
        },
        // 水平滚动时的滚动速度，即每秒滚动多少rpx，这有利于控制文字无论多少时，都能有一个恒定的速度
        speed: {
            type: [Number, String],
            default: 160
        },
        // 播放状态，play-播放，paused-暂停
        playState: {
            type: String,
            default: 'play'
        },
        // 通知的边距
        padding: {
            type: [Number, String],
            default: '18rpx 24rpx'
        }
    },
    data() {
        return {
            textWidth: 0, // 滚动的文字宽度
            boxWidth: 0, // 供文字滚动的父盒子的宽度，和前者一起为了计算滚动速度
            animationDuration: '10s', // 动画执行时间
            animationPlayState: 'paused', // 动画的开始和结束执行
            showText: '' // 显示的文本
        };
    },
    watch: {
        list: {
            immediate: true,
            handler(val) {
                this.showText = val.join('，');
                this.$nextTick(() => {
                    this.initSize();
                });
            }
        },
        playState(val) {
            if(val == 'play') this.animationPlayState = 'running';
            else this.animationPlayState = 'paused';
        },
        speed(val) {
            this.initSize();
        }
    },
    computed: {
        // 计算字体颜色，如果没有自定义的，就用uview主题颜色
        computeColor() {
            if (this.color) return this.color;
            // 如果是无主题，就默认使用content-color
            else if(this.type == 'none') return '#606266';
            else return this.type;
        },
        // 文字内容的样式
        textStyle() {
            let style = {};
            if (this.color) style.color = this.color;
            else if(this.type == 'none') style.color = '#606266';
            style.fontSize = this.fontSize + 'rpx';
            return style;
        },
        // 计算背景颜色
        computeBgColor() {
            if (this.bgColor) return this.bgColor;
            else if(this.type == 'none') return 'transparent';
        }
    },
    mounted() {
        this.$nextTick(() => {
            this.initSize();
        });
    },
    methods: {
        initSize() {
            let query = [],
                boxWidth = 0,
                textWidth = 0;
            let textQuery = new Promise((resolve, reject) => {
                uni.createSelectorQuery()
                    .in(this)
                    .select(`#u-notice-content`)
                    .boundingClientRect()
                    .exec(ret => {
                        this.textWidth = ret[0].width;
                        resolve();
                    });
            });
            query.push(textQuery);
            Promise.all(query).then(() => {
                // 根据t=s/v(时间=路程/速度)，这里为何不需要加上#u-notice-box的宽度，因为中设置了.u-notice-content样式中设置了padding-left: 100%
                // 恰巧计算出来的结果中已经包含了#u-notice-box的宽度
                this.animationDuration = `${this.textWidth / uni.upx2px(this.speed)}s`;
                // 这里必须这样开始动画，否则在APP上动画速度不会改变(HX版本2.4.6，IOS13)
                this.animationPlayState = 'paused';
                setTimeout(() => {
                    if(this.playState == 'play' && this.autoplay) this.animationPlayState = 'running';
                }, 10);
            });
        },
        // 点击通告栏
        click(index) {
            this.$emit('click');
        },
        // 点击关闭按钮
        close() {
            this.$emit('close');
        },
        // 点击更多箭头按钮
        getMore() {
            this.$emit('getMore');
        }
    }
};
</script>

<style lang="scss" scoped>
@import "../../libs/css/style.components.scss";
    
.u-notice-bar {
    padding: 18rpx 24rpx;
    overflow: hidden;
}

.u-direction-row {
    @include vue-flex;
    align-items: center;
    justify-content: space-between;
}

.u-left-icon {
    /* #ifndef APP-NVUE */
    display: inline-flex;
    /* #endif */
    align-items: center;
}

.u-notice-box {
    flex: 1;
    @include vue-flex;
    overflow: hidden;
    margin-left: 12rpx;
}

.u-right-icon {
    margin-left: 12rpx;
    display: inline-flex;
    align-items: center;
}

.u-notice-content {
    animation: u-loop-animation 10s linear infinite both;
    text-align: right;
    // 这一句很重要，为了能让滚动左右连接起来
    padding-left: 100%;
    @include vue-flex;
    flex-wrap: nowrap;
}

.u-notice-text {
    font-size: 26rpx;
    word-break: keep-all;
    white-space: nowrap
}

@keyframes u-loop-animation {
    0% {
        transform: translate3d(0, 0, 0);
    }

    100% {
        transform: translate3d(-100%, 0, 0);
    }
}
</style>
